package com.eastseeway.radioproject.calibration;

import android.app.Application;
import android.os.Handler;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.eastseeway.radioproject.R;
import com.eastseeway.radioproject.base.BaseViewModel;
import com.eastseeway.radioproject.base.Const;
import com.eastseeway.radioproject.engineer.EngineerItemBean;
import com.eastseeway.radioproject.entities.BeanVBus;
import com.eastseeway.radioproject.entities.BottomBoardFunctionCode;
import com.eastseeway.radioproject.utils.CommandGenerator;
import com.eastseeway.radioproject.utils.SPHelper;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;

import struct.StructException;

public class CalibrationViewModel extends BaseViewModel<CalibrationRepository> {
    private final MutableLiveData<Float> vBusValue = new MutableLiveData<>( 1f);
    private final MutableLiveData<Byte> freq = new MutableLiveData<>((byte)1);
    private final MutableLiveData<Boolean> hasPressure = new MutableLiveData<>(true);
    private final MutableLiveData<Byte> power = new MutableLiveData<>((byte)1);
    private final MutableLiveData<Byte> time = new MutableLiveData<>((byte)10);
    private final MutableLiveData<String> phaseVoltage = new MutableLiveData<>("");
    private final MutableLiveData<String> handleType = new MutableLiveData<>("1");
    private final MutableLiveData<Integer> pressure = new MutableLiveData<>(30);
    private final MutableLiveData<String> pressure_info = new MutableLiveData<>("");
    private final MutableLiveData<String> handle_info = new MutableLiveData<>("");
    private final MutableLiveData<String> autoState = new MutableLiveData<>("开始自动校准");
    public CalibrationViewModel(@NonNull Application application) {
        super(application);
    }
    @Override
    protected CalibrationRepository setRepository() {
        return new CalibrationRepository();
    }
    public void onPowerCheckedChange(int checkedId){
        switch (checkedId) {
            case R.id.MHz_1: freq.setValue((byte)1);break;
            case R.id.MHz_2: freq.setValue((byte)2);break;
        }
    }
    public void onHandleTypeChange(int checkedId) {
        switch (checkedId) {
            case R.id.hanPressure:
                handleType.setValue("1");
                sendMessageToSwitch((byte)1);
                break;
            case R.id.noPressure:
                handleType.setValue("0");
                sendMessageToSwitch((byte)0);
                break;
        }
    }
    void sendMessageToSwitch(byte msg){
        try {
            byte[] bytes = CommandGenerator.commandToSwitchBoard(Const.ADDRESS_TO_SWITCH_BOARD, msg, msg, msg);
            sendMessage(bytes);
        } catch (StructException e) {throw new RuntimeException(e);}

    }
    public void onVBusAdd1(){
        BigDecimal value = new BigDecimal(String.valueOf(getVBusValue().getValue()));
        getVBusValue().setValue(value.add(BigDecimal.ONE).setScale(1, RoundingMode.HALF_UP).floatValue());
    }
    public void onVBusMinus1(){
        BigDecimal value = new BigDecimal(String.valueOf(getVBusValue().getValue()));
        getVBusValue().setValue(value.subtract(BigDecimal.ONE).setScale(1, RoundingMode.HALF_UP).floatValue());
    }
    public void onVBusAdd_1(){
        BigDecimal decimal = new BigDecimal(String.valueOf(getVBusValue().getValue()));
        getVBusValue().setValue(decimal.add(new BigDecimal("0.1")).floatValue());
    }
    public void onVBusMinus_1(){
        BigDecimal decimal = new BigDecimal(String.valueOf(getVBusValue().getValue()));
        getVBusValue().setValue(decimal.subtract(new BigDecimal("0.1")).floatValue());
    }
    public void onSave(){
        sendHandleCommand(true);
        saveVBusToDataBase();
    }
    public void onClear(){
        mRepository.deleteByHandleType(handleType.getValue());
    }
    public void onPowerAdd(){
        if (power.getValue() >= 50) {return;}
        power.setValue((byte) (power.getValue() + 1));
    }
    public void onPowerMinus(){
        if (power.getValue() <= 1) {return;}
        power.setValue((byte) (power.getValue() - 1));
    }
    public void onTimeAdd(){
        time.setValue((byte) (time.getValue() + 1));
    }
    public void onTimeMinus(){
        if (time.getValue() <= 10) {return;}
        time.setValue((byte) (time.getValue() - 1));
    }
    public void onPressureAdd1(){
        pressure.setValue(pressure.getValue() + 1);
    }
    public void onPressureMinus1(){
        if (pressure.getValue() <= 1) {return;}
        pressure.setValue(pressure.getValue() - 1);
    }
    public void open(){
        try {
            sendMessage(CommandGenerator.commandData1ToHandle1(false));
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    public void close(){
        try {
            sendMessage(CommandGenerator.commandData1ToHandle1(true));
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    public void onSendPressure(){
        try {
            int pressureOffset = SPHelper.getPressureOffset(getApplication());
            byte[] command2NegativePressureBoard = CommandGenerator.command2NegativePressureBoard(Const.ADDRESS_TO_NEGATIVE_PRESSURE_BOARD, -((pressure.getValue()+pressureOffset)*100), 0, 0, 0);
            sendMessage(command2NegativePressureBoard);
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    public void saveVBusToDataBase(){
        try {
            BeanVBus beanVBus = new BeanVBus();
            beanVBus.setId(handleType.getValue()+ freq.getValue() + power.getValue());
            beanVBus.setHandle_type(handleType.getValue());
            beanVBus.setFreq(String.valueOf(freq.getValue()));
            beanVBus.setPower(power.getValue());
            beanVBus.setVoltage(String.valueOf(getVBusValue().getValue()));
            mRepository.insertVBusData(beanVBus);
        }catch (NullPointerException | NumberFormatException e){
            throw new RuntimeException(e);
        }
    }

    public void insertVBusList(List<BeanVBus> vBusList){
        mRepository.insertVBusList(vBusList);
    }


    public void onSendVBus(){
        sendHandleCommand(false);
        new Handler().postDelayed(this::sendPreCommand,50);
    }
//    生成启动自动校准的命令，用转换版的Bean
    public void onAutoCalibration(){
        try {
            sendMessage(CommandGenerator.commandToSwitchBoard(Const.ADDRESS_TO_AUTO_CALIBRATION, (byte)0x01, (byte)0x00,(byte)0x00));
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    void sendPreCommand() {
        try {
            byte[] commandToEnergyBoard = CommandGenerator.commandToEnergyBoard(Const.ADDRESS_TO_ENERGY_BOARD, freq.getValue(),true, true,true, 0, time.getValue());
//            short vBusVoltage = SPHelper.getVBusVoltage(getApplication());
            byte[] commandToBottomBoard = CommandGenerator.command2BottomBoard(Const.ADDRESS_TO_BOTTOM_BOARD, BottomBoardFunctionCode.cmd_bottombrd_Vbus_Set, (short) (getVBusValue().getValue() * 100));
//            byte[] commandToNegativePressureBoard = CommandGenerator.command2NegativePressureBoard(Const.ADDRESS_TO_NEGATIVE_PRESSURE_BOARD, getSkinPressure().getValue() * -100, 0, 0, 0);
            ByteBuffer buffer = ByteBuffer.allocate(commandToEnergyBoard.length + commandToBottomBoard.length);
            buffer.put(commandToEnergyBoard);
            buffer.put(commandToBottomBoard);
            sendMessage(buffer.array());
        } catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    void sendHandleCommand(boolean isCalibration){
        try {
            if (phaseVoltage.getValue().isEmpty()) {
                return;
            }
            byte[] data2ToHandle = CommandGenerator.commandCalibrationDataToHandle(hasPressure.getValue() ? Const.ADDRESS_TO_HANDLE_1_DATA_CALIBRATION : Const.ADDRESS_TO_HANDLE_2_DATA_CALIBRATION,
                    isCalibration,
                    (short) (power.getValue() * 1000),
                    (byte) (freq.getValue()-1));
            sendMessage(data2ToHandle);
        }catch (StructException e) {
            throw new RuntimeException(e);
        }
    }
    public LiveData<List<BeanVBus>> queryAll(){
        return mRepository.queryAllVBus();
    }
    public LiveData<List<BeanVBus>> queryP1(){
        return mRepository.queryVBusList("1","1");
    }
    public LiveData<List<BeanVBus>> queryP2(){
        return mRepository.queryVBusList("1","2");
    }
    public LiveData<List<BeanVBus>> queryNP1(){
        return mRepository.queryVBusList("0","1");
    }
    public LiveData<List<BeanVBus>> queryNP2(){
        return mRepository.queryVBusList("0","2");
    }
    public MutableLiveData<Byte> getFreq() {
        return freq;
    }
    public MutableLiveData<Float> getVBusValue() {
        return vBusValue;
    }
    public MutableLiveData<Byte> getPower() {return power;}
    public MutableLiveData<Byte> getTime() {return time;}
    public MutableLiveData<String> getPhaseVoltage() {
        return phaseVoltage;
    }
    public MutableLiveData<Boolean> getHasPressure() {
        return hasPressure;
    }
    public MutableLiveData<Integer> getPressure() {return pressure;}
    public MutableLiveData<String> getPressure_info() {return pressure_info;}
    public MutableLiveData<String> getHandle_info() {return handle_info;}
    public MutableLiveData<String> getHandleType() {return handleType;}
    public MutableLiveData<String> getAutoState() {return autoState;}
}
